/**
 * ============JWT认证中间件模块开始===========
 * JWT认证中间件 - JWT Authentication Middleware
 * 
 * 功能说明：
 * - 验证用户身份，保护需要登录才能访问的API端点
 * - 支持标准的Bearer Token认证方式
 * - 提供可选认证和管理员权限验证功能
 * - 基于JWT令牌的无状态认证机制
 * 
 * 依赖模块：
 * - jsonwebtoken: JWT令牌处理库，用于生成和验证令牌
 * - UserModel: 用户数据模型，用于验证用户存在性
 * 
 * 中间件类型：
 * - authMiddleware: 必需认证中间件
 * - optionalAuth: 可选认证中间件
 * - adminAuth: 管理员权限中间件
 * 
 * 应用场景：
 * - 保护需要登录的API端点
 * - 用户身份验证和授权
 * - 管理员权限控制
 * - 无状态的分布式认证
 * 
 * 设计原则：
 * - 安全性优先，严格验证令牌
 * - 详细的错误处理和日志记录
 * - 支持多种认证场景
 * - 遵循JWT最佳实践
 * 
 * Provides comprehensive JWT authentication with multiple middleware options
 */

// 导入必要的依赖包 - Import necessary dependencies
import jwt from 'jsonwebtoken';                    // JWT令牌处理库 - JWT token handling library
import { UserModel } from '../models/userModel.js'; // 用户数据模型 - User data model

/**
 * ============主要认证中间件开始===========
 * JWT认证中间件 - 验证用户身份
 * JWT Authentication Middleware - Verify user identity
 * 
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 * @param {Function} next - Express下一个中间件函数
 * @returns {void} 继续执行下一个中间件或返回错误响应
 * 
 * 功能说明：
 * - 从HTTP请求头中提取JWT令牌
 * - 验证令牌格式和有效性
 * - 解码令牌获取用户信息
 * - 验证用户是否存在于数据库中
 * - 将用户信息附加到请求对象上
 * 
 * 工作流程：
 * 1. 提取Authorization请求头
 * 2. 验证Bearer格式
 * 3. 解码JWT令牌
 * 4. 验证用户存在性
 * 5. 设置req.user对象
 * 6. 继续执行下一个中间件
 * 
 * 认证头格式：
 * Authorization: Bearer <JWT_TOKEN>
 * 
 * 错误处理：
 * - 401: 认证失败（令牌无效、过期、格式错误等）
 * - 500: 服务器内部错误
 * 
 * 使用示例：
 * router.get('/protected', authMiddleware, (req, res) => {
 *   // req.user 包含已认证的用户信息
 *   res.json({ user: req.user });
 * });
 * 
 * 安全考虑：
 * - 使用环境变量存储JWT密钥
 * - 详细的令牌验证和错误处理
 * - 防止令牌泄露和重放攻击
 * - 支持令牌过期和刷新机制
 */
const authMiddleware = async (req, res, next) => {
  try {
    // 第一步：从请求头中获取Authorization字段 - Step 1: Get Authorization header from request
    const authHeader = req.headers.authorization;
    
    // 检查是否提供了认证头 - Check if authentication header is provided
    if (!authHeader) {
      return res.status(401).json({
        success: false,
        message: '未提供认证令牌 - No authentication token provided',
        error: 'NO_TOKEN_PROVIDED'
      });
    }

    // 第二步：检查Bearer格式 - Step 2: Check Bearer format
    // 标准的JWT令牌格式应该是 "Bearer <token>" - Standard JWT token format should be "Bearer <token>"
    if (!authHeader.startsWith('Bearer ')) {
      return res.status(401).json({
        success: false,
        message: '认证令牌格式错误 - Invalid token format',
        error: 'INVALID_TOKEN_FORMAT'
      });
    }

    // 第三步：提取实际的token - Step 3: Extract actual token
    const token = authHeader.substring(7); // 移除 "Bearer " 前缀 - Remove "Bearer " prefix

    // 检查token是否为空 - Check if token is empty
    if (!token) {
      return res.status(401).json({
        success: false,
        message: '认证令牌为空 - Empty authentication token',
        error: 'EMPTY_TOKEN'
      });
    }

    // 第四步：验证和解码token - Step 4: Verify and decode token
    const jwtSecret = process.env.JWT_SECRET || 'your-secret-key'; // 从环境变量获取密钥 - Get secret from environment variables
    let decoded;
    
    try {
      // 使用JWT库验证令牌的有效性和完整性 - Use JWT library to verify token validity and integrity
      decoded = jwt.verify(token, jwtSecret);
    } catch (jwtError) {
      // 根据不同的JWT错误类型返回相应的错误信息 - Return appropriate error message based on JWT error type
      let errorMessage = '认证令牌无效 - Invalid authentication token';
      let errorCode = 'INVALID_TOKEN';
      
      if (jwtError.name === 'TokenExpiredError') {
        errorMessage = '认证令牌已过期 - Authentication token expired';
        errorCode = 'TOKEN_EXPIRED';
      } else if (jwtError.name === 'JsonWebTokenError') {
        errorMessage = '认证令牌格式错误 - Malformed authentication token';
        errorCode = 'MALFORMED_TOKEN';
      } else if (jwtError.name === 'NotBeforeError') {
        errorMessage = '认证令牌尚未生效 - Authentication token not active yet';
        errorCode = 'TOKEN_NOT_ACTIVE';
      }
      
      return res.status(401).json({
        success: false,
        message: errorMessage,
        error: errorCode
      });
    }

    // 第五步：验证用户是否存在 - Step 5: Verify user exists
    const user = await UserModel.findById(decoded.userId);
    if (!user) {
      return res.status(401).json({
        success: false,
        message: '用户不存在 - User not found',
        error: 'USER_NOT_FOUND'
      });
    }

    // 第六步：将用户信息添加到请求对象中 - Step 6: Add user info to request object
    req.user = {
      id: user.id,
      phone: user.phone,
      email: user.email,
      nickname: user.nickname,
      birthDate: user.birthDate,
      birthTime: user.birthTime,
      gender: user.gender,
      location: user.location,
      createdAt: user.createdAt
    };

    // 第七步：继续执行下一个中间件 - Step 7: Continue to next middleware
    next();
    
  } catch (error) {
    // 异常处理：记录错误并返回服务器错误响应 - Exception handling: log error and return server error response
    console.error('认证中间件错误 - Authentication middleware error:', error);
    return res.status(500).json({
      success: false,
      message: '认证过程中发生错误 - Error occurred during authentication',
      error: 'AUTHENTICATION_ERROR'
    });
  }
};

/**
 * ============可选认证中间件开始===========
 * 可选认证中间件 - 如果有token则验证，没有则继续
 * Optional authentication middleware - verify if token exists, continue if not
 * 
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 * @param {Function} next - Express下一个中间件函数
 * @returns {void} 继续执行下一个中间件
 * 
 * 功能说明：
 * - 如果请求头中包含认证令牌，则进行验证
 * - 如果没有提供令牌，则设置req.user为null并继续
 * - 适用于既支持匿名访问又支持认证访问的接口
 * - 不会因为缺少令牌而阻止请求继续执行
 * 
 * 使用场景：
 * - 公开接口但需要区分用户身份
 * - 个性化内容展示（登录用户显示更多信息）
 * - 统计和分析需要用户信息但不强制登录
 * 
 * 使用示例：
 * router.get('/public-content', optionalAuth, (req, res) => {
 *   if (req.user) {
 *     // 已登录用户，返回个性化内容
 *     res.json({ content: 'personalized', user: req.user });
 *   } else {
 *     // 匿名用户，返回通用内容
 *     res.json({ content: 'general' });
 *   }
 * });
 * 
 * 行为说明：
 * - 有效令牌：设置req.user为用户信息
 * - 无效令牌：调用标准认证中间件处理错误
 * - 无令牌：设置req.user为null，继续执行
 */
export const optionalAuth = async (req, res, next) => {
  try {
    // 检查是否提供了认证头 - Check if authentication header is provided
    const authHeader = req.headers.authorization;
    
    // 如果没有提供token，直接继续 - If no token provided, continue directly
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      req.user = null; // 设置用户为null - Set user to null
      return next();
    }

    // 如果提供了token，则进行验证 - If token provided, verify it
    return authMiddleware(req, res, next);
    
  } catch (error) {
    // 可选认证出错时，设置用户为null并继续 - On optional auth error, set user to null and continue
    console.error('可选认证中间件错误 - Optional auth middleware error:', error);
    req.user = null;
    next();
  }
};

/**
 * ============管理员权限中间件开始===========
 * 管理员权限中间件 - 验证管理员身份
 * Admin permission middleware - verify admin identity
 * 
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 * @param {Function} next - Express下一个中间件函数
 * @returns {void} 继续执行下一个中间件或返回错误响应
 * 
 * 功能说明：
 * - 首先进行普通用户认证
 * - 然后验证用户是否具有管理员权限
 * - 保护需要管理员权限的API端点
 * - 支持分级权限管理
 * 
 * 工作流程：
 * 1. 调用标准认证中间件验证用户身份
 * 2. 从数据库获取用户详细信息
 * 3. 检查用户是否具有管理员权限
 * 4. 验证通过则继续，否则返回403错误
 * 
 * 使用场景：
 * - 管理后台接口保护
 * - 系统配置和设置接口
 * - 用户管理和权限控制
 * - 敏感数据操作接口
 * 
 * 使用示例：
 * router.delete('/admin/users/:id', adminAuth, (req, res) => {
 *   // 只有管理员可以删除用户
 *   // req.user 包含已验证的管理员信息
 * });
 * 
 * 权限级别：
 * - 普通用户：isAdmin = false
 * - 管理员：isAdmin = true
 * - 超级管理员：isSuperAdmin = true（可扩展）
 * 
 * 错误处理：
 * - 401: 认证失败
 * - 403: 权限不足（非管理员）
 * - 500: 服务器内部错误
 */
export const adminAuth = async (req, res, next) => {
  try {
    // 第一步：首先进行普通用户认证 - Step 1: First perform regular user authentication
    await new Promise((resolve, reject) => {
      authMiddleware(req, res, (err) => {
        if (err) reject(err);
        else resolve();
      });
    });

    // 第二步：检查用户是否为管理员 - Step 2: Check if user is admin
    const user = await UserModel.findById(req.user.id);
    
    // 验证用户是否存在（双重检查） - Verify user exists (double check)
    if (!user) {
      return res.status(401).json({
        success: false,
        message: '用户不存在 - User not found',
        error: 'USER_NOT_FOUND'
      });
    }
    
    // 检查管理员权限 - Check admin permission
    if (!user.isAdmin) {
      return res.status(403).json({
        success: false,
        message: '需要管理员权限 - Admin permission required',
        error: 'ADMIN_REQUIRED'
      });
    }

    // 第三步：权限验证通过，继续执行 - Step 3: Permission verified, continue execution
    next();
    
  } catch (error) {
    // 异常处理：记录错误并返回服务器错误响应 - Exception handling: log error and return server error response
    console.error('管理员认证中间件错误 - Admin auth middleware error:', error);
    return res.status(500).json({
      success: false,
      message: '权限验证过程中发生错误 - Error occurred during permission verification',
      error: 'ADMIN_AUTH_ERROR'
    });
  }
};

/**
 * ============中间件导出开始===========
 * 导出认证中间件供应用使用
 * Export authentication middleware for app use
 * 
 * 导出说明：
 * - authMiddleware: 默认导出，必需认证中间件
 * - optionalAuth: 命名导出，可选认证中间件
 * - adminAuth: 命名导出，管理员权限中间件
 * 
 * 使用示例：
 * import authMiddleware, { optionalAuth, adminAuth } from './middleware/auth.js';
 * 
 * // 保护需要登录的路由
 * router.get('/profile', authMiddleware, getUserProfile);
 * 
 * // 可选认证的路由
 * router.get('/content', optionalAuth, getContent);
 * 
 * // 管理员专用路由
 * router.delete('/admin/users/:id', adminAuth, deleteUser);
 */
export default authMiddleware;
// ============JWT认证中间件模块结束===========